This is an R Markdown Notebook. When you execute code within the notebook, the results appear beneath the code.

Try executing this chunk by clicking the Run button within the chunk or by placing your cursor inside it and pressing Ctrl+Shift+Enter.

```r
plot(cars)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxubGlicmFyeShvc21kYXRhKVxubGlicmFyeShzZilcbmxpYnJhcnkoZ2dwbG90MilcbmxpYnJhcnkocGxvdGx5KVxubGlicmFyeShyZ2VvcylcbmxpYnJhcnkodGlkeXZlcnNlKVxuYGBgIn0= -->

```r
library(osmdata)
library(sf)
library(ggplot2)
library(plotly)
library(rgeos)
library(tidyverse)
Registered S3 methods overwritten by 'dbplyr':
  method         from
  print.tbl_lazy     
  print.tbl_sql      
── Attaching packages ────────────────────────────────────────────────────────────────────────────────────────── tidyverse 1.3.1 ──
✔ tibble  3.1.7     ✔ dplyr   1.0.9
✔ tidyr   1.2.0     ✔ stringr 1.4.0
✔ readr   2.1.2     ✔ forcats 0.5.1
✔ purrr   0.3.4     
── Conflicts ───────────────────────────────────────────────────────────────────────────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks plotly::filter(), stats::filter()
✖ dplyr::lag()    masks stats::lag()
get_overpass_url()
[1] "https://overpass-api.de/api/interpreter"

FYI all osmdata object can be combined using the c() operator. This c() operation can only be performed on simple feature (sf) type geographic features. I.e. you have to use osmdata_sf() to create the simple feature or convert sp type features to sf type features. I think that calling the bbox based on the county perimeter is better. There are some campuses that are not labeled only “University of Georgia” explicity, so it may be best to use st_… methods to get landuse polygons based on the UGA operator key and then use those polygons to filter and select UGA buildings. I could also use the trim_osmdata() function to select from the list of all UGA operated landuse polygons and run through them, one-by-one and obtain a building list that way. I need to use format_out = “polygon” in the getbb() function in order for this to work. There may be some edge-cases (e.g. building is on UGA campus landuse polygon, yet is not a UGA operated building.) that lead me to think that simply adding operator=“University of Georgia” to each building is worth the effort.

Pro-tip: value_exact needs to be false in order for match_case to also be false and not fail the query.

bb_county <- getbb('Athens-Clarke County')
all_Buildings <- opq(bbox = bb_county) %>%
  add_osm_feature(key = "building") %>%
  add_osm_feature(key = "operator", value = "University of Georgia", value_exact = FALSE, match_case = FALSE) %>%
  osmdata_sf()

Nonnecessary ggplotly code below.

p <- ggplot() + geom_sf(data = a$osm_polygons,
  fill = 'light blue') + theme_minimal()

ggplotly()
ugaCampus <- opq(bbox = bb_county) %>%
  add_osm_feature(key = "landuse", value = "property") %>%
  add_osm_feature(key = "name", value = "University of Georgia", value_exact = FALSE, match_case = FALSE) %>%
  osmdata_sf()
#Create sf dataset of the UGA campus polygons.
ugaCampus <- ugaCampus$osm_polygons

This query allows me to access the multipolygon that comprises the UGA campus. I will then use this to create a bbox based on this multipolygon. I need to also filter out only the polygons from this multipolygon that are explicitly labeled as universities (i.e. amenity = university).

ugaCampus <- ugaCampus %>% filter(amenity == "university")
all_Bicycle_Nodes <- opq(bbox =bb_county) %>%
  add_osm_feature(key = "amenity", value = "bicycle_parking") %>%
  osmdata_sf()
all_Bicycle_Nodes <- all_Bicycle_Nodes$osm_points

Filter only bicycle nodes within the UGA campus.

mat = st_intersects(all_Bicycle_Nodes, ugaCampus, sparse = FALSE)

mat <- apply(mat, 1, any)

all_Bicycle_Nodes_Trimmed <- all_Bicycle_Nodes[mat,]

st_bbox for polygons.

q <- ggplot() + geom_sf(data = all_bicycle_nodes_untrimmed$osm_points,
  fill = 'light blue') + theme_minimal()

ggplotly()
building_Bike_Combined_Data <- c(all_Bicycle_Nodes_Untrimmed, all_Buildings)

ggplotly interactive map of UGA buildings and bike racks.

q <- ggplot() + geom_sf(data = building_Bike_Combined_Data$osm_points,
  fill = 'light blue') + theme_minimal() + geom_sf(data = building_Bike_Combined_Data$osm_polygons,
  fill = 'light blue') + theme_minimal()
ggplotly()

I will try to create a list by appending the trimmed osmdata from the all_buildings_untrimmed list. The 6th and 8th lists in the osmdata type contain polygons and multipolygons respectively.

append throws an error when I try to append a list of lists with no values. So I will run the trim_osmdata and get six different trim_osmdata function to produce a list of list of lists.

bb_trim <- getbb('University of Georgia', featuretype = 'University', format_out = "polygon")

#Initial list:
all_Buildings <- list()

for(i in 1:length(bb_trim))
  all_Buildings[1][i] <- trim_osmdata(all_buildings_untrimmed, bb_trim[i])
Warning in all_Buildings[1][i] <- trim_osmdata(all_buildings_untrimmed,  :
  number of items to replace is not a multiple of replacement length
Warning in all_Buildings[1][i] <- trim_osmdata(all_buildings_untrimmed,  :
  number of items to replace is not a multiple of replacement length
Warning in all_Buildings[1] <- `*vtmp*` :
  number of items to replace is not a multiple of replacement length

b is building c is bike nodes. Think code is only able to do simple polygons at the time. I will need to add multi-polygon ability in the future.

b <- building_Bike_Combined_Data$osm_polygons
c <- building_Bike_Combined_Data$osm_points
##  First project data into a planar coordinate system (here UTM zone 32)
#utmStr <- "+proj=EPSG:2240 +zone=%d +datum=NAD83 +units=ft +no_defs +ellps=WGS84"
utmStr <- "+proj=EPSG:2240 +zone=%d +datum=WGS84 +units=ft +no_defs +ellps=GRS80"
crs <- st_crs(2240)
#utmStr <- "+proj=utm +zone=%d +datum=NAD83 +units=m +no_defs +ellps=GRS80"
#crs <- CRS(sprintf(utmStr, 32))
#Perform spatial transform on bike nodes and building polygons\

pUTM <- st_transform(b, crs)
ptsUTM <- st_transform(c, crs)
## Set up containers for results
n <- nrow(ptsUTM)
nearestBuilding <- character(n)
distToNearestBuilding <- numeric(n)

The st_nearest_feature function may also be really useful here.I think I would like to add a column to the original unprojected simple feature type.

## For each point, find name of nearest polygon (in this case, UGA buildings)
for (i in seq_along(nearestBuilding)) {
    gDists <- st_distance(ptsUTM[i,], pUTM, byid=TRUE)
    nearestBuilding[i] <- pUTM$name[which.min(gDists)]
    distToNearestBuilding[i] <- min(gDists)
}
Warning in overlay(...) :
  reverting 'unnamed.chunk.label' to 'unnamed-chunk' for duration of render
pUTM$name
  [1] NA                                              
  [2] "Milledge Hall"                                 
  [3] "Fine Arts Scenery Workshop"                    
  [4] "Memorial Hall"                                 
  [5] "Chemistry Storage Building"                    
  [6] NA                                              
  [7] NA                                              
  [8] "Baptist Student Union"                         
  [9] "UGA Health Center"                             
 [10] "Lake Herrick Pavilion"                         
 [11] "Richard B. Russell Special Collections Library"
 [12] "Lucy Cobb Carriage House"                      
 [13] "Lucy Cobb Washhouse"                           
 [14] NA                                              
 [15] "Seney-Stovall Chapel"                          
 [16] "Lucy Cobb"                                     
 [17] NA                                              
 [18] NA                                              
 [19] "Carnegie Library Learning Center"              
 [20] "Brown Hall"                                    
 [21] "Winnie Davis"                                  
 [22] "Russell Hall HSC"                              
 [23] "Scott Hall"                                    
 [24] "Quarters A"                                    
 [25] "Hudson Hall"                                   
 [26] "B.S. Miller Hall"                              
 [27] "George Hall"                                   
 [28] "Quarters B"                                    
 [29] "Central Heating Plant"                         
 [30] "Rhodes Hall"                                   
 [31] NA                                              
 [32] NA                                              
 [33] "Wright Hall"                                   
 [34] NA                                              
 [35] NA                                              
 [36] NA                                              
 [37] "Pound Hall"                                    
 [38] "Oglethorpe Dining Commons"                     
 [39] NA                                              
 [40] NA                                              
 [41] "Science Learning Center"                       
 [42] "Bolton Dining Commons"                         
 [43] "Four Towers"                                   
 [44] "Benson Hall"                                   
 [45] "District Energy Plant #1"                      
 [46] "Moore-Rooker Hall"                             
 [47] "Correll Hall"                                  
 [48] "Amos Hall"                                     
 [49] "Herrick Pavilion Boat House"                   
 [50] NA                                              
 [51] "Locomotive Diagnostic Center"                  
 [52] "Rhodes Animal Science Center - C"              
 [53] "Rhodes Animal Science Center - B"              
 [54] "Joe Frank Harris Dining Commons"               
 [55] "Facilities Management East"                    
 [56] "Rhodes Animal Science Center - A"              
 [57] "Perfoming Arts Center"                         
 [58] "Hugh Hodgson School of Music"                  
 [59] "Georgia Museum of Art"                         
 [60] "Ceramics"                                      
 [61] "Building 2130"                                 
 [62] "Tucker Hall"                                   
 [63] "US Forest Service"                             
 [64] "US Forest Service"                             
 [65] "Electronics Shop"                              
 [66] "Hoke Smith Annex"                              
 [67] "Hoke Smith Cooperative Extension Building"     
 [68] "Housing and Consumer Research Center"          
 [69] "Family Science Center 1"                       
 [70] NA                                              
 [71] NA                                              
 [72] "Family Science Center 2"                       
 [73] NA                                              
 [74] "Financial Planning Research Center"            
 [75] NA                                              
 [76] NA                                              
 [77] NA                                              
 [78] NA                                              
 [79] NA                                              
 [80] NA                                              
 [81] "Reed Plaza East Restroom"                      
 [82] "Reed Plaza Concession Building"                
 [83] NA                                              
 [84] "Reed Plaza West Restroom"                      
 [85] NA                                              
 [86] NA                                              
 [87] "Tate Deck Booth 1"                             
 [88] "Tate Deck Booth 1"                             
 [89] "Psychology Building"                           
 [90] "Anthropology Greenhouse"                       
 [91] "North Campus Parking Deck"                     
 [92] "Tate Center Parking Deck"                      
 [93] "Dean William Tate Student Center"              
 [94] "Mechanical Building"                           
 [95] "Carl Vinson Hall"                              
 [96] "Margaret Hall"                                 
 [97] "Handball Court"                                
 [98] "Wheeler Hall"                                  
 [99] NA                                              
[100] NA                                              
[101] NA                                              
[102] NA                                              
[103] NA                                              
[104] NA                                              
[105] NA                                              
[106] NA                                              
[107] NA                                              
[108] NA                                              

For each point, find name of nearest polygon (in this case, UGA buildings)

for (i in seq_along(nearestBuilding)) { gDists <- st_distance(ptsUTM[i,], pUTM, byid=TRUE) nearestBuilding[i] <- pUTM$name[i] distToNearestBuilding[i] <- min(gDists)

## Check that it worked
nearestDistanceName <- data.frame(nearestBuilding, distToNearestBuilding)
#       nearestCanton distToNearestCanton
# 1             Wiltz           15342.222
# 2        Echternach            7470.728
# 3            Remich           20520.800
# 4          Clervaux            6658.167
# 5        Echternach           22177.771
# 6          Clervaux           26388.388
# 7           Redange            8135.764
# 8            Remich            2199.394
# 9  Esch-sur-Alzette           11776.534
# 10           Remich           14998.204

plot(c, pch=16, col="red")
Warning: plotting the first 9 out of 22 attributes; use max.plot = 22 to plot all
#text(c, 1:10, pos=3)
plot(b, add=TRUE)
Warning in plot.sf(b, add = TRUE) :
  ignoring all but the first attribute
text(b, b$name, cex=0.7)

Add a new chunk by clicking the Insert Chunk button on the toolbar or by pressing Ctrl+Alt+I.

When you save the notebook, an HTML file containing the code and output will be saved alongside it (click the Preview button or press Ctrl+Shift+K to preview the HTML file).

The preview shows you a rendered HTML copy of the contents of the editor. Consequently, unlike Knit, Preview does not run any R code chunks. Instead, the output of the chunk when it was last run in the editor is displayed.

LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiANCg0KVHJ5IGV4ZWN1dGluZyB0aGlzIGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkN0cmwrU2hpZnQrRW50ZXIqLiANCg0KYGBge3J9DQpwbG90KGNhcnMpDQpgYGANCg0KYGBge3J9DQpsaWJyYXJ5KG9zbWRhdGEpDQpsaWJyYXJ5KHNmKQ0KbGlicmFyeShnZ3Bsb3QyKQ0KbGlicmFyeShwbG90bHkpDQpsaWJyYXJ5KHJnZW9zKQ0KbGlicmFyeSh0aWR5dmVyc2UpDQpgYGANCg0KYGBge3J9DQpnZXRfb3ZlcnBhc3NfdXJsKCkNCmBgYA0KRllJIGFsbCBvc21kYXRhIG9iamVjdCBjYW4gYmUgY29tYmluZWQgdXNpbmcgdGhlIGMoKSBvcGVyYXRvci4gVGhpcyBjKCkgb3BlcmF0aW9uIGNhbiBvbmx5IGJlIHBlcmZvcm1lZCBvbiBzaW1wbGUgZmVhdHVyZSAoc2YpIHR5cGUgZ2VvZ3JhcGhpYyBmZWF0dXJlcy4gSS5lLiB5b3UgaGF2ZSB0byB1c2Ugb3NtZGF0YV9zZigpIHRvIGNyZWF0ZSB0aGUgc2ltcGxlIGZlYXR1cmUgb3IgY29udmVydCBzcCB0eXBlIGZlYXR1cmVzIHRvIHNmIHR5cGUgZmVhdHVyZXMuIEkgdGhpbmsgdGhhdCBjYWxsaW5nIHRoZSBiYm94IGJhc2VkIG9uIHRoZSBjb3VudHkgcGVyaW1ldGVyIGlzIGJldHRlci4gVGhlcmUgYXJlIHNvbWUgY2FtcHVzZXMgdGhhdCBhcmUgbm90IGxhYmVsZWQgb25seSAiVW5pdmVyc2l0eSBvZiBHZW9yZ2lhIiBleHBsaWNpdHksIHNvIGl0IG1heSBiZSBiZXN0IHRvIHVzZSBzdF8uLi4gbWV0aG9kcyB0byBnZXQgbGFuZHVzZSBwb2x5Z29ucyBiYXNlZCBvbiB0aGUgVUdBIG9wZXJhdG9yIGtleSBhbmQgdGhlbiB1c2UgdGhvc2UgcG9seWdvbnMgdG8gZmlsdGVyIGFuZCBzZWxlY3QgVUdBIGJ1aWxkaW5ncy4gSSBjb3VsZCBhbHNvIHVzZSB0aGUgdHJpbV9vc21kYXRhKCkgZnVuY3Rpb24gdG8gc2VsZWN0IGZyb20gdGhlIGxpc3Qgb2YgYWxsIFVHQSBvcGVyYXRlZCBsYW5kdXNlIHBvbHlnb25zIGFuZCBydW4gdGhyb3VnaCB0aGVtLCBvbmUtYnktb25lIGFuZCBvYnRhaW4gYSBidWlsZGluZyBsaXN0IHRoYXQgd2F5LiBJIG5lZWQgdG8gdXNlIGZvcm1hdF9vdXQgPSAicG9seWdvbiIgaW4gdGhlIGdldGJiKCkgZnVuY3Rpb24gaW4gb3JkZXIgZm9yIHRoaXMgdG8gd29yay4gVGhlcmUgbWF5IGJlIHNvbWUgZWRnZS1jYXNlcyAoZS5nLiBidWlsZGluZyBpcyBvbiBVR0EgY2FtcHVzIGxhbmR1c2UgcG9seWdvbiwgeWV0IGlzIG5vdCBhIFVHQSBvcGVyYXRlZCBidWlsZGluZy4pIHRoYXQgbGVhZCBtZSB0byB0aGluayB0aGF0IHNpbXBseSBhZGRpbmcgb3BlcmF0b3I9IlVuaXZlcnNpdHkgb2YgR2VvcmdpYSIgdG8gZWFjaCBidWlsZGluZyBpcyB3b3J0aCB0aGUgZWZmb3J0Lg0KDQpQcm8tdGlwOiB2YWx1ZV9leGFjdCBuZWVkcyB0byBiZSBmYWxzZSBpbiBvcmRlciBmb3IgbWF0Y2hfY2FzZSB0byBhbHNvIGJlIGZhbHNlIGFuZCBub3QgZmFpbCB0aGUgcXVlcnkuDQoNCmBgYHtyfQ0KYmJfY291bnR5IDwtIGdldGJiKCdBdGhlbnMtQ2xhcmtlIENvdW50eScpDQphbGxfQnVpbGRpbmdzIDwtIG9wcShiYm94ID0gYmJfY291bnR5KSAlPiUNCiAgYWRkX29zbV9mZWF0dXJlKGtleSA9ICJidWlsZGluZyIpICU+JQ0KICBhZGRfb3NtX2ZlYXR1cmUoa2V5ID0gIm9wZXJhdG9yIiwgdmFsdWUgPSAiVW5pdmVyc2l0eSBvZiBHZW9yZ2lhIiwgdmFsdWVfZXhhY3QgPSBGQUxTRSwgbWF0Y2hfY2FzZSA9IEZBTFNFKSAlPiUNCiAgb3NtZGF0YV9zZigpDQpgYGANCg0KTm9ubmVjZXNzYXJ5IGdncGxvdGx5IGNvZGUgYmVsb3cuDQoNCmBgYHtyfQ0KcCA8LSBnZ3Bsb3QoKSArIGdlb21fc2YoZGF0YSA9IGEkb3NtX3BvbHlnb25zLA0KICBmaWxsID0gJ2xpZ2h0IGJsdWUnKSArIHRoZW1lX21pbmltYWwoKQ0KDQpnZ3Bsb3RseSgpDQpgYGANCg0KYGBge3J9DQp1Z2FDYW1wdXMgPC0gb3BxKGJib3ggPSBiYl9jb3VudHkpICU+JQ0KICBhZGRfb3NtX2ZlYXR1cmUoa2V5ID0gImxhbmR1c2UiLCB2YWx1ZSA9ICJwcm9wZXJ0eSIpICU+JQ0KICBhZGRfb3NtX2ZlYXR1cmUoa2V5ID0gIm5hbWUiLCB2YWx1ZSA9ICJVbml2ZXJzaXR5IG9mIEdlb3JnaWEiLCB2YWx1ZV9leGFjdCA9IEZBTFNFLCBtYXRjaF9jYXNlID0gRkFMU0UpICU+JQ0KICBvc21kYXRhX3NmKCkNCiNDcmVhdGUgc2YgZGF0YXNldCBvZiB0aGUgVUdBIGNhbXB1cyBwb2x5Z29ucy4NCnVnYUNhbXB1cyA8LSB1Z2FDYW1wdXMkb3NtX3BvbHlnb25zDQpgYGANClRoaXMgcXVlcnkgYWxsb3dzIG1lIHRvIGFjY2VzcyB0aGUgbXVsdGlwb2x5Z29uIHRoYXQgY29tcHJpc2VzIHRoZSBVR0EgY2FtcHVzLg0KSSB3aWxsIHRoZW4gdXNlIHRoaXMgdG8gY3JlYXRlIGEgYmJveCBiYXNlZCBvbiB0aGlzIG11bHRpcG9seWdvbi4gSSBuZWVkIHRvIGFsc28NCmZpbHRlciBvdXQgb25seSB0aGUgcG9seWdvbnMgZnJvbSB0aGlzIG11bHRpcG9seWdvbiB0aGF0IGFyZSBleHBsaWNpdGx5IGxhYmVsZWQNCmFzIHVuaXZlcnNpdGllcyAoaS5lLiBhbWVuaXR5ID0gdW5pdmVyc2l0eSkuDQoNCmBgYHtyfQ0KdWdhQ2FtcHVzIDwtIHVnYUNhbXB1cyAlPiUgZmlsdGVyKGFtZW5pdHkgPT0gInVuaXZlcnNpdHkiKQ0KYGBgDQoNCg0KDQoNCmBgYHtyfQ0KYWxsX0JpY3ljbGVfTm9kZXMgPC0gb3BxKGJib3ggPWJiX2NvdW50eSkgJT4lDQogIGFkZF9vc21fZmVhdHVyZShrZXkgPSAiYW1lbml0eSIsIHZhbHVlID0gImJpY3ljbGVfcGFya2luZyIpICU+JQ0KICBvc21kYXRhX3NmKCkNCmFsbF9CaWN5Y2xlX05vZGVzIDwtIGFsbF9CaWN5Y2xlX05vZGVzJG9zbV9wb2ludHMNCmBgYA0KDQpGaWx0ZXIgb25seSBiaWN5Y2xlIG5vZGVzIHdpdGhpbiB0aGUgVUdBIGNhbXB1cy4NCg0KYGBge3J9DQptYXQgPSBzdF9pbnRlcnNlY3RzKGFsbF9CaWN5Y2xlX05vZGVzLCB1Z2FDYW1wdXMsIHNwYXJzZSA9IEZBTFNFKQ0KDQptYXQgPC0gYXBwbHkobWF0LCAxLCBhbnkpDQoNCmFsbF9CaWN5Y2xlX05vZGVzX1RyaW1tZWQgPC0gYWxsX0JpY3ljbGVfTm9kZXNbbWF0LF0NCmBgYA0KDQpzdF9iYm94IGZvciBwb2x5Z29ucy4NClwNCmBgYHtyfQ0KcSA8LSBnZ3Bsb3QoKSArIGdlb21fc2YoZGF0YSA9IGFsbF9iaWN5Y2xlX25vZGVzX3VudHJpbW1lZCRvc21fcG9pbnRzLA0KICBmaWxsID0gJ2xpZ2h0IGJsdWUnKSArIHRoZW1lX21pbmltYWwoKQ0KDQpnZ3Bsb3RseSgpDQpgYGANCg0KDQpgYGB7cn0NCmJ1aWxkaW5nX0Jpa2VfQ29tYmluZWRfRGF0YSA8LSBjKGFsbF9CaWN5Y2xlX05vZGVzX1VudHJpbW1lZCwgYWxsX0J1aWxkaW5ncykNCmBgYA0KDQpnZ3Bsb3RseSBpbnRlcmFjdGl2ZSBtYXAgb2YgVUdBIGJ1aWxkaW5ncyBhbmQgYmlrZSByYWNrcy4NCg0KYGBge3J9DQpxIDwtIGdncGxvdCgpICsgZ2VvbV9zZihkYXRhID0gYnVpbGRpbmdfQmlrZV9Db21iaW5lZF9EYXRhJG9zbV9wb2ludHMsDQogIGZpbGwgPSAnbGlnaHQgYmx1ZScpICsgdGhlbWVfbWluaW1hbCgpICsgZ2VvbV9zZihkYXRhID0gYnVpbGRpbmdfQmlrZV9Db21iaW5lZF9EYXRhJG9zbV9wb2x5Z29ucywNCiAgZmlsbCA9ICdsaWdodCBibHVlJykgKyB0aGVtZV9taW5pbWFsKCkNCmdncGxvdGx5KCkNCmBgYA0KDQpJIHdpbGwgdHJ5IHRvIGNyZWF0ZSBhIGxpc3QgYnkgYXBwZW5kaW5nIHRoZSB0cmltbWVkIG9zbWRhdGEgZnJvbSB0aGUgYWxsX2J1aWxkaW5nc191bnRyaW1tZWQgbGlzdC4gVGhlIDZ0aCBhbmQgOHRoIGxpc3RzIGluIHRoZSBvc21kYXRhIHR5cGUgY29udGFpbiBwb2x5Z29ucyBhbmQgbXVsdGlwb2x5Z29ucyByZXNwZWN0aXZlbHkuDQoNCmFwcGVuZCB0aHJvd3MgYW4gZXJyb3Igd2hlbiBJIHRyeSB0byBhcHBlbmQgYSBsaXN0IG9mIGxpc3RzIHdpdGggbm8gdmFsdWVzLiBTbyBJIHdpbGwgcnVuIHRoZSB0cmltX29zbWRhdGEgYW5kIGdldCBzaXggZGlmZmVyZW50IHRyaW1fb3NtZGF0YSBmdW5jdGlvbiB0byBwcm9kdWNlIGEgbGlzdCBvZiBsaXN0IG9mIGxpc3RzLg0KYGBge3J9DQpiYl90cmltIDwtIGdldGJiKCdVbml2ZXJzaXR5IG9mIEdlb3JnaWEnLCBmZWF0dXJldHlwZSA9ICdVbml2ZXJzaXR5JywgZm9ybWF0X291dCA9ICJwb2x5Z29uIikNCg0KI0luaXRpYWwgbGlzdDoNCmFsbF9CdWlsZGluZ3MgPC0gbGlzdCgpDQo9DQpmb3IoaSBpbiAxOmxlbmd0aChiYl90cmltKSkNCiAgYWxsX0J1aWxkaW5nc1sxXVtpXSA8LSB0cmltX29zbWRhdGEoYWxsX2J1aWxkaW5nc191bnRyaW1tZWQsIGJiX3RyaW1baV0pDQpgYGANCmIgaXMgYnVpbGRpbmcgYyBpcyBiaWtlIG5vZGVzLiBUaGluayBjb2RlIGlzIG9ubHkgYWJsZSB0byBkbyBzaW1wbGUgcG9seWdvbnMgYXQgdGhlIHRpbWUuIEkgd2lsbCBuZWVkIHRvIGFkZCBtdWx0aS1wb2x5Z29uIGFiaWxpdHkgaW4gdGhlIGZ1dHVyZS4NCmBgYHtyfQ0KYiA8LSBidWlsZGluZ19CaWtlX0NvbWJpbmVkX0RhdGEkb3NtX3BvbHlnb25zDQpjIDwtIGJ1aWxkaW5nX0Jpa2VfQ29tYmluZWRfRGF0YSRvc21fcG9pbnRzDQpgYGANCg0KYGBge3J9DQojIyAgRmlyc3QgcHJvamVjdCBkYXRhIGludG8gYSBwbGFuYXIgY29vcmRpbmF0ZSBzeXN0ZW0gKGhlcmUgVVRNIHpvbmUgMzIpDQojdXRtU3RyIDwtICIrcHJvaj1FUFNHOjIyNDAgK3pvbmU9JWQgK2RhdHVtPU5BRDgzICt1bml0cz1mdCArbm9fZGVmcyArZWxscHM9V0dTODQiDQp1dG1TdHIgPC0gIitwcm9qPUVQU0c6MjI0MCArem9uZT0lZCArZGF0dW09V0dTODQgK3VuaXRzPWZ0ICtub19kZWZzICtlbGxwcz1HUlM4MCINCmNycyA8LSBzdF9jcnMoMjI0MCkNCiN1dG1TdHIgPC0gIitwcm9qPXV0bSArem9uZT0lZCArZGF0dW09TkFEODMgK3VuaXRzPW0gK25vX2RlZnMgK2VsbHBzPUdSUzgwIg0KI2NycyA8LSBDUlMoc3ByaW50Zih1dG1TdHIsIDMyKSkNCiNQZXJmb3JtIHNwYXRpYWwgdHJhbnNmb3JtIG9uIGJpa2Ugbm9kZXMgYW5kIGJ1aWxkaW5nIHBvbHlnb25zXA0KDQpwVVRNIDwtIHN0X3RyYW5zZm9ybShiLCBjcnMpDQpwdHNVVE0gPC0gc3RfdHJhbnNmb3JtKGMsIGNycykNCmBgYA0KDQoNCmBgYHtyfQ0KIyMgU2V0IHVwIGNvbnRhaW5lcnMgZm9yIHJlc3VsdHMNCm4gPC0gbnJvdyhwdHNVVE0pDQpuZWFyZXN0QnVpbGRpbmcgPC0gY2hhcmFjdGVyKG4pDQpkaXN0VG9OZWFyZXN0QnVpbGRpbmcgPC0gbnVtZXJpYyhuKQ0KYnVpbGRpbmdDYXBhY2l0eSA8LSBudW1lcmljKG4pDQpidWlsZGluZ0NvdW50IDwtIG51bWVyaWMobikNCmJ1aWxkaW5nUmFja1R5cGUgPC0gY2hhcmFjdGVyKG4pDQpidWlsZGluZ1JhY2tDb3ZlcmVkIDwtIGNoYXJhY3RlcihuKQ0KDQpgYGANCg0KVGhlIHN0X25lYXJlc3RfZmVhdHVyZSBmdW5jdGlvbiBtYXkgYWxzbyBiZSByZWFsbHkgdXNlZnVsIGhlcmUuSSB0aGluayBJIHdvdWxkIGxpa2UgdG8gYWRkIGEgY29sdW1uIHRvIHRoZSBvcmlnaW5hbCB1bnByb2plY3RlZCBzaW1wbGUgZmVhdHVyZSB0eXBlLiANCmBgYHtyfQ0KIyMgRm9yIGVhY2ggcG9pbnQsIGZpbmQgbmFtZSBvZiBuZWFyZXN0IHBvbHlnb24gKGluIHRoaXMgY2FzZSwgVUdBIGJ1aWxkaW5ncykNCmZvciAoaSBpbiBzZXFfYWxvbmcobmVhcmVzdEJ1aWxkaW5nKSkgew0KICAgIGJ1aWxkaW5nQ2FwYWNpdHkgPC0gcHRzVVRNJGNhcGFjaXR5W2ksXQ0KICAgIA0KICAgIGdEaXN0cyA8LSBzdF9kaXN0YW5jZShwdHNVVE1baSxdLCBwVVRNLCBieWlkPVRSVUUpDQogICAgbmVhcmVzdEJ1aWxkaW5nW2ldIDwtIHBVVE0kbmFtZVt3aGljaC5taW4oZ0Rpc3RzKV0NCiAgICBkaXN0VG9OZWFyZXN0QnVpbGRpbmdbaV0gPC0gbWluKGdEaXN0cykNCn0NCmBgYA0KDQojIyBGb3IgZWFjaCBwb2ludCwgZmluZCBuYW1lIG9mIG5lYXJlc3QgcG9seWdvbiAoaW4gdGhpcyBjYXNlLCBVR0EgYnVpbGRpbmdzKQ0KZm9yIChpIGluIHNlcV9hbG9uZyhuZWFyZXN0QnVpbGRpbmcpKSB7DQogICAgZ0Rpc3RzIDwtIHN0X2Rpc3RhbmNlKHB0c1VUTVtpLF0sIHBVVE0sIGJ5aWQ9VFJVRSkNCiAgICBuZWFyZXN0QnVpbGRpbmdbaV0gPC0gcFVUTSRuYW1lW2ldDQogICAgZGlzdFRvTmVhcmVzdEJ1aWxkaW5nW2ldIDwtIG1pbihnRGlzdHMpDQoNCg0KYGBge3J9DQojIyBDaGVjayB0aGF0IGl0IHdvcmtlZA0KbmVhcmVzdERpc3RhbmNlTmFtZSA8LSBkYXRhLmZyYW1lKG5lYXJlc3RCdWlsZGluZywgZGlzdFRvTmVhcmVzdEJ1aWxkaW5nKQ0KIyAgICAgICBuZWFyZXN0Q2FudG9uIGRpc3RUb05lYXJlc3RDYW50b24NCiMgMSAgICAgICAgICAgICBXaWx0eiAgICAgICAgICAgMTUzNDIuMjIyDQojIDIgICAgICAgIEVjaHRlcm5hY2ggICAgICAgICAgICA3NDcwLjcyOA0KIyAzICAgICAgICAgICAgUmVtaWNoICAgICAgICAgICAyMDUyMC44MDANCiMgNCAgICAgICAgICBDbGVydmF1eCAgICAgICAgICAgIDY2NTguMTY3DQojIDUgICAgICAgIEVjaHRlcm5hY2ggICAgICAgICAgIDIyMTc3Ljc3MQ0KIyA2ICAgICAgICAgIENsZXJ2YXV4ICAgICAgICAgICAyNjM4OC4zODgNCiMgNyAgICAgICAgICAgUmVkYW5nZSAgICAgICAgICAgIDgxMzUuNzY0DQojIDggICAgICAgICAgICBSZW1pY2ggICAgICAgICAgICAyMTk5LjM5NA0KIyA5ICBFc2NoLXN1ci1BbHpldHRlICAgICAgICAgICAxMTc3Ni41MzQNCiMgMTAgICAgICAgICAgIFJlbWljaCAgICAgICAgICAgMTQ5OTguMjA0DQoNCnBsb3QoYywgcGNoPTE2LCBjb2w9InJlZCIpDQojdGV4dChjLCAxOjEwLCBwb3M9MykNCnBsb3QoYiwgYWRkPVRSVUUpDQp0ZXh0KGIsIGIkbmFtZSwgY2V4PTAuNykNCmBgYA0KDQoNCg0KDQoNCg0KQWRkIGEgbmV3IGNodW5rIGJ5IGNsaWNraW5nIHRoZSAqSW5zZXJ0IENodW5rKiBidXR0b24gb24gdGhlIHRvb2xiYXIgb3IgYnkgcHJlc3NpbmcgKkN0cmwrQWx0K0kqLg0KDQpXaGVuIHlvdSBzYXZlIHRoZSBub3RlYm9vaywgYW4gSFRNTCBmaWxlIGNvbnRhaW5pbmcgdGhlIGNvZGUgYW5kIG91dHB1dCB3aWxsIGJlIHNhdmVkIGFsb25nc2lkZSBpdCAoY2xpY2sgdGhlICpQcmV2aWV3KiBidXR0b24gb3IgcHJlc3MgKkN0cmwrU2hpZnQrSyogdG8gcHJldmlldyB0aGUgSFRNTCBmaWxlKS4NCg0KVGhlIHByZXZpZXcgc2hvd3MgeW91IGEgcmVuZGVyZWQgSFRNTCBjb3B5IG9mIHRoZSBjb250ZW50cyBvZiB0aGUgZWRpdG9yLiBDb25zZXF1ZW50bHksIHVubGlrZSAqS25pdCosICpQcmV2aWV3KiBkb2VzIG5vdCBydW4gYW55IFIgY29kZSBjaHVua3MuIEluc3RlYWQsIHRoZSBvdXRwdXQgb2YgdGhlIGNodW5rIHdoZW4gaXQgd2FzIGxhc3QgcnVuIGluIHRoZSBlZGl0b3IgaXMgZGlzcGxheWVkLg0K